//
//  Line.h
//  Vector_Math
//
//  Created by John R Peterson on 3/11/12.
//  Copyright 2012 __MyCompanyName__. All rights reserved.
//

#ifndef Vector_Math_Line_h
#define Vector_Math_Line_h

#include "LinAlg.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/*
 *  Uses covariance matricies to construct best fit lines quickly
 */
typedef struct Line_struct {
    Vec_list *points;   // points contained in this line
    Vec *centroid;      // centroid of the line
    Matrix *Sigma;      // covariance matrix of points on the line 
    Vec *direction;   // direction of the line the major axis
    Vec *Lambda;        // vector of eigenvalues
} Line;

typedef struct PolyLine_struct {
    Vec_list *vertices; // all of the vertices in the line
    Line **Llist;       // list of the lines contained within the list
    int size;           // how many lines does the list contain
    int maxsize;        // how many lines can the list contain
    
    // also need to keep track of where we are on the polyline
    int pos;            // index of which line we are on so only check 3 lines total for each calculation
} PolyLine;

// Line Function prototypes
Line* Line_init(Vec_list *P);           // initializes with atleast 2 points
Line* Line_2Point(Vec *a, Vec *b);      // initializes with 2 points
void Line_add(Line *this, Vec *v);
void Line_addMany(Line *this, Vec_list *vlist);
void Line_destroy(Line *this);
void Line_destroyR(Line *this);            // destroys the line and all points it contains
float Line_distance(Line *this, Vec *p);
float Line_distanceP(Line *this, Vec *p);
float Line_length(Line *this);

// PolyLine Function Prototypes
PolyLine* PolyLine_init(Vec_list *verticies);
void PolyLine_addVertexEnd(PolyLine *this, Vec *v);
void PolyLine_destroy(PolyLine *this);              // destroys the polyline, and all of the lines it has constructed along with its vertex list, doesn't destroy the verticies that polyline was given or created with
float PolyLine_error(PolyLine *this, Vec *pos);     // computes perpendicular error to polyline
void PolyLine_removeVertexStart(PolyLine *this);    // removes vertex from the polyline, and from the associated list, destroys the line, but doesn't destroy the vertex
void PolyLine_removeVertexRStart(PolyLine *this); // destroys the underlying vertex aswell

#endif
